package com.tous.modules.service;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import jakarta.annotation.PreDestroy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeUnit;

/**
 * @author mengwei
 * @description UdpServer
 * @createDate 2025/7/16 15:38
 */
@Component
public class UdpServer {

    private static final Logger logger = LoggerFactory.getLogger(UdpServer.class);

    private final Bootstrap bootstrap;
    @Value("${udp.server.port}")
    private  int port;
    private EventLoopGroup group;
    private Channel channel;
    private Instant startTime;

    public UdpServer(Bootstrap bootstrap, EventLoopGroup group) {
        this.bootstrap = bootstrap;
        this.group = group;
    }

    public synchronized void start() throws InterruptedException {
        if (isRunning()) {
            logger.info("UDP服务器已在运行，端口: {}", port);
            return;
        }
        try {
            // 绑定端口并启动服务器
            ChannelFuture future = bootstrap.bind(new InetSocketAddress(port)).sync();
            channel = future.channel();
            startTime = Instant.now();
            logger.info("UDP服务器已启动，监听端口: {}", port);

            // 添加关闭钩子
            Runtime.getRuntime().addShutdownHook(new Thread(this::stop));
        } catch (InterruptedException e) {
            logger.warn("启动UDP服务器失败: 抛出异常处理");
            // 释放资源
            if (channel != null) {
                channel.close();
                channel = null;
            }
            throw e;
        }
    }

    @PreDestroy
    public synchronized void stop() {
        if (!isRunning()) {
            logger.info("UDP服务器未运行，无需停止");
            return;
        }

        try {
            logger.info("正在停止UDP服务器...");

            if (channel != null) {
                channel.close().sync();
                channel = null;
            }

            if (group != null) {
                group.shutdownGracefully(0, 5, TimeUnit.SECONDS).sync();
                group = null;
            }

            logger.info("UDP服务器已成功停止");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            logger.error("停止UDP服务器失败", e);
        }
    }

    public boolean isRunning() {
        return channel != null && channel.isOpen();
    }

    public int getPort() {
        return port;
    }

    public Duration getUptime() {
        return startTime != null ? Duration.between(startTime, Instant.now()) : Duration.ZERO;
    }

}
